#include "configmanager.h"

#include <Core/logger/logger.h>
#include <Core/config/config.h>
#include <Core/config/configfile.h>

namespace Optra{

class ConfigManagerPrivate
{
public:
    ConfigManagerPrivate(){}
    ~ConfigManagerPrivate(){}

    QMap<Opl::Core::Entity::EntityId, QSharedPointer<Opl::Core::IConfig> > configs;
    static ConfigManager* instance;
};

ConfigManager::ConfigManager(QObject *parent) :
    QObject(parent), O_PRIVATE_CREATE(ConfigManager)
{
    O_D(ConfigManager);
}

ConfigManager::~ConfigManager()
{
    O_D(ConfigManager);
    O_PRIVATE_DELETE;
}

void ConfigManager::registerConfig(Opl::Core::Entity::EntityId id, const QString &path, bool createIfNotExists)
{
    O_D(ConfigManager);

    QFileInfo configFile(path);
    if (!configFile.exists())
    {
        if (createIfNotExists)
        {

        }

        //TODO::Add invalid path logic
        //throw std::exception("Invalid config path");
    }

    LI.Info() << "Register config:" << id << " for:" << path;
    QSharedPointer<Opl::Core::IConfig> ptr(new Opl::Core::ConfigFile(path));
    ptr->load();
    d->configs.insert(id, ptr);
}

Opl::Core::IConfig *ConfigManager::configFor(Opl::Core::Entity::EntityId id)
{
    //TODO: consider action for missing config
    O_D(ConfigManager);
    LI.Trace() << "Access config for:" << id;
    if (d->configs.contains(id))
        return d->configs.value(id).data();
    return 0;
}

QVariant ConfigManager::value(Opl::Core::Entity::EntityId id, const QString &section, const QString &key, const QVariant &def)
{
    O_D(ConfigManager);
    Opl::Core::IConfig* c = configFor(id);
    if (c == 0)
        return def;
    return c->value(section, key, def);
}

bool ConfigManager::setValue(Opl::Core::Entity::EntityId id, const QString &section, const QString &key, const QVariant &val)
{
    O_D(ConfigManager);
    Opl::Core::IConfig* c = configFor(id);
    if (c == 0)
        return false;

    c->setValue(section, key, val);
    return true;
}

ConfigManager *ConfigManager::instance()
{
    static ConfigManager instance;
    return &instance;
}

}
